package sk.vrto.web;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import sk.vrto.domain.EmailAccount;
import sk.vrto.domain.User;
import sk.vrto.service.crypto.SaltGenerator;
import sk.vrto.service.crypto.SaltedAESStringEncrypter;
import sk.vrto.service.dao.ContactRepository;
import sk.vrto.service.dao.EmailRepository;
import sk.vrto.service.dao.hibernate.HibernateContactRepository;
import sk.vrto.service.dao.hibernate.HibernateEmailRepository;
import sk.vrto.service.dao.inmemory.InMemoryContactRepository;
import sk.vrto.service.dao.inmemory.InMemoryEmailRepository;
import sk.vrto.service.domain.ContactCreator;
import sk.vrto.service.email.EmailService;
import sk.vrto.service.email.EmailServiceImpl;
import sk.vrto.service.email.SmtPropertiesFactory;
import sk.vrto.web.presenters.*;

// Injector
// creates dependencies and assembles them to presenters
public class ApplicationInjector {

    // dependencies
    private static final User user;
    private static final ContactRepository contactRepository;
    private static final EmailRepository emailRepository;
    private static final EmailService emailService;
    private static SessionFactory sessionFactory;

    // lazy presenters
    private static final EmailApplicationPresenter emailApplicationPresenter;
    private static final ContactPresenter contactPresenter;
    private static final ContactsListPresenter contactsListPresenter;
    private static final NewContactPresenter newContactPresenter;
    private static final NewEmailPresenter newEmailPresenter;
    private static final EmailsPresenter emailsPresenter;

    // Assembles graph
    static {
        sessionFactory = new Configuration().configure().buildSessionFactory();
        SaltedAESStringEncrypter encrypter = new SaltedAESStringEncrypter(new SaltGenerator());
        user = new User("testuser", "testuser", new EmailAccount("diplomka.misova@hotmail.com",
                encrypter.encrypt("5RocnikFRI")));//TODO login

//        contactRepository = new InMemoryContactRepository(new ContactCreator());
//        ((InMemoryContactRepository) contactRepository).initForUser(user);
//        emailRepository = new InMemoryEmailRepository(contactRepository);
//        ((InMemoryEmailRepository) emailRepository).initForUser(user);
        contactRepository = new HibernateContactRepository(new ContactCreator());
        emailRepository = new HibernateEmailRepository();

        emailService = new EmailServiceImpl(SmtPropertiesFactory.hotmailProperties(), encrypter);

        emailApplicationPresenter = new EmailApplicationPresenter();
        contactPresenter = new ContactPresenter(contactRepository);
        contactsListPresenter = new ContactsListPresenter(contactRepository, user);
        newContactPresenter = new NewContactPresenter(contactRepository, user);
        newEmailPresenter = new NewEmailPresenter(contactRepository, emailService, user);
        emailsPresenter = new EmailsPresenter(emailRepository, user);
    }

    public static  EmailApplicationPresenter getEmailApplicationPresenter() {
        return emailApplicationPresenter;
    }

    public static ContactPresenter getContactPresenter() {
        return contactPresenter;
    }

    public static ContactsListPresenter getContactsListPresenter() {
        return contactsListPresenter;
    }

    public static NewContactPresenter getNewContactPresenter() {
        return newContactPresenter;
    }

    public static NewEmailPresenter getNewEmailPresenter() {
        return newEmailPresenter;
    }

    // prototype scope
    public static EmailPresenter getEmailPresenter() {
        return new EmailPresenter(emailRepository);
    }

    public static EmailsPresenter getEmailsPresenter() {
        return emailsPresenter;
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void rebuildSessionFactory() {
        sessionFactory = new Configuration().configure().buildSessionFactory();
    }
}
